home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / cagd_lib / bsp_sym.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-30  |  10.8 KB  |  383 lines

  1. /******************************************************************************
  2. * SBsp_Sym.c - Bspline surface symbolic computation.                  *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Sep. 92.                          *
  5. ******************************************************************************/
  6.  
  7. #include "cagd_loc.h"
  8.  
  9. static CagdCrvStruct *BspCrvMultAux(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
  10. static CagdSrfStruct *BspSrfMultAux(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);
  11.  
  12. /******************************************************************************
  13. * Given two bspline curves - multiply them coordinatewise.              *
  14. * The two curves are promoted to same point type before the multiplication    *
  15. * can take place. The bspline curves are subdivided into piecewise bezier     *
  16. * curves, each is multiplied individually and then all curves are merged.     *
  17. * Return a bspline curves representing their product.                  *
  18. ******************************************************************************/
  19. CagdCrvStruct *BspCrvMult(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2)
  20. {
  21.     CagdCrvStruct *ProdCrv, *TCrv;
  22.  
  23.     Crv1 = CagdCrvCopy(Crv1);
  24.     Crv2 = CagdCrvCopy(Crv2);
  25.     if (!CagdMakeCrvsCompatible(&Crv1, &Crv2, FALSE, FALSE))
  26.     FATAL_ERROR(CAGD_ERR_CRV_FAIL_CMPT);
  27.  
  28.     TCrv = BspCrvMultAux(Crv1, Crv2);
  29.  
  30.     if (CAGD_IS_BEZIER_CRV(TCrv)) {
  31.     ProdCrv = CnvrtBezier2BsplineCrv(TCrv);
  32.     CagdCrvFree(TCrv);
  33.     }
  34.     else
  35.     ProdCrv = TCrv;
  36.  
  37.     CagdCrvFree(Crv1);
  38.     CagdCrvFree(Crv2);
  39.  
  40.     return ProdCrv;
  41. }
  42.  
  43. /******************************************************************************
  44. * Auxiliary routine. Subdivides the curves into Bezier curves, multiply       *
  45. * the Bezier curves and merge them back. All is done simultaneously.          *
  46. ******************************************************************************/
  47. static CagdCrvStruct *BspCrvMultAux(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2)
  48. {
  49.     CagdCrvStruct *Crv1a, *Crv1b, *Crv2a, *Crv2b, *CrvA, *CrvB, *ProdCrv;
  50.  
  51.     if (Crv1 -> Order != Crv1 -> Length ||
  52.     Crv2 -> Order != Crv2 -> Length) {
  53.     CagdRType SubdivVal = Crv1 -> Order != Crv1 -> Length ?
  54.                 Crv1 -> KnotVector[(Crv1 -> Length +
  55.                             Crv1 -> Order) / 2] :
  56.                 Crv2 -> KnotVector[(Crv2 -> Length +
  57.                             Crv2 -> Order) / 2];
  58.  
  59.     /* Subdivide. */
  60.     Crv1a = BspCrvSubdivAtParam(Crv1, SubdivVal);
  61.     Crv1b = Crv1a -> Pnext;
  62.     Crv1a -> Pnext = NULL;
  63.  
  64.     Crv2a = BspCrvSubdivAtParam(Crv2, SubdivVal);
  65.     Crv2b = Crv2a -> Pnext;
  66.     Crv2a -> Pnext = NULL;
  67.  
  68.     CrvA = BspCrvMultAux(Crv1a, Crv2a);
  69.     CrvB = BspCrvMultAux(Crv1b, Crv2b);
  70.     CagdCrvFree(Crv1a);
  71.     CagdCrvFree(Crv1b);
  72.     CagdCrvFree(Crv2a);
  73.     CagdCrvFree(Crv2b);
  74.  
  75.     ProdCrv = CagdMergeCrvCrv(CrvA, CrvB);
  76.     CagdCrvFree(CrvA);
  77.     CagdCrvFree(CrvB);
  78.     }
  79.     else {
  80.     int i;
  81.     CagdRType TMin, TMax;
  82.     CagdCrvStruct
  83.         *Crv1Bzr = CnvrtBspline2BezierCrv(Crv1),
  84.         *Crv2Bzr = CnvrtBspline2BezierCrv(Crv2),
  85.         *ProdCrvAux = BzrCrvMult(Crv1Bzr, Crv2Bzr);
  86.  
  87.     CagdCrvDomain(Crv1, &TMin, &TMax);
  88.     ProdCrv = CnvrtBezier2BsplineCrv(ProdCrvAux);
  89.     for (i = 0; i < ProdCrv -> Order; i++) {
  90.         ProdCrv -> KnotVector[i] = TMin;
  91.         ProdCrv -> KnotVector[i + ProdCrv -> Order] = TMax;
  92.     }
  93.  
  94.     CagdCrvFree(Crv1Bzr);
  95.     CagdCrvFree(Crv2Bzr);
  96.     CagdCrvFree(ProdCrvAux);
  97.     }
  98.  
  99.     return ProdCrv;
  100. }
  101.  
  102. /******************************************************************************
  103. * Given two bspline surfaces - multiply them coordinatewise.              *
  104. * The two surfaces are promoted to same point type before the multiplication  *
  105. * can take place. The bspline surfaces are subdivided into piecewise bezier   *
  106. * patches, each is multiplied individually and then all patches are merged.   *
  107. * Return a bspline surface representing their product.                  *
  108. ******************************************************************************/
  109. CagdSrfStruct *BspSrfMult(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2)
  110. {
  111.     CagdSrfStruct *ProdSrf, *TSrf;
  112.  
  113.     Srf1 = CagdSrfCopy(Srf1);
  114.     Srf2 = CagdSrfCopy(Srf2);
  115.     if (!CagdMakeSrfsCompatible(&Srf1, &Srf2, FALSE, FALSE, FALSE, FALSE))
  116.     FATAL_ERROR(CAGD_ERR_SRF_FAIL_CMPT);
  117.  
  118.     TSrf = BspSrfMultAux(Srf1, Srf2);
  119.  
  120.     if (CAGD_IS_BEZIER_SRF(TSrf)) {
  121.     ProdSrf = CnvrtBezier2BsplineSrf(TSrf);
  122.     CagdSrfFree(TSrf);
  123.     }
  124.     else
  125.     ProdSrf = TSrf;
  126.  
  127.     CagdSrfFree(Srf1);
  128.     CagdSrfFree(Srf2);
  129.  
  130.     return ProdSrf;
  131. }
  132.  
  133. /******************************************************************************
  134. * Auxiliary routine. Subdivides the surfaces into Bezier patches, multiply    *
  135. * the Bezier patches and merge them back. All is done simultaneously.         *
  136. ******************************************************************************/
  137. static CagdSrfStruct *BspSrfMultAux(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2)
  138. {
  139.     CagdSrfStruct *Srf1a, *Srf1b, *Srf2a, *Srf2b, *SrfA, *SrfB, *ProdSrf;
  140.  
  141.     if (Srf1 -> UOrder != Srf1 -> ULength ||
  142.     Srf2 -> UOrder != Srf2 -> ULength) {
  143.     CagdRType SubdivVal = Srf1 -> UOrder != Srf1 -> ULength ?
  144.                 Srf1 -> UKnotVector[(Srf1 -> ULength +
  145.                              Srf1 -> UOrder) / 2] :
  146.                 Srf2 -> UKnotVector[(Srf2 -> ULength +
  147.                              Srf2 -> UOrder) / 2];
  148.  
  149.     /* Subdivide along U. */
  150.     Srf1a = BspSrfSubdivAtParam(Srf1, SubdivVal, CAGD_CONST_U_DIR);
  151.     Srf1b = Srf1a -> Pnext;
  152.     Srf1a -> Pnext = NULL;
  153.  
  154.     Srf2a = BspSrfSubdivAtParam(Srf2, SubdivVal, CAGD_CONST_U_DIR);
  155.     Srf2b = Srf2a -> Pnext;
  156.     Srf2a -> Pnext = NULL;
  157.  
  158.     SrfA = BspSrfMultAux(Srf1a, Srf2a);
  159.     SrfB = BspSrfMultAux(Srf1b, Srf2b);
  160.     CagdSrfFree(Srf1a);
  161.     CagdSrfFree(Srf1b);
  162.     CagdSrfFree(Srf2a);
  163.     CagdSrfFree(Srf2b);
  164.  
  165.     ProdSrf = CagdMergeSrfSrf(SrfA, SrfB, CAGD_CONST_U_DIR, TRUE);
  166.     CagdSrfFree(SrfA);
  167.     CagdSrfFree(SrfB);
  168.     }
  169.     else if (Srf1 -> VOrder != Srf1 -> VLength) {
  170.     CagdRType SubdivVal = Srf1 -> VOrder != Srf1 -> VLength ?
  171.                 Srf1 -> VKnotVector[(Srf1 -> VLength +
  172.                              Srf1 -> VOrder) / 2] :
  173.                 Srf2 -> VKnotVector[(Srf2 -> VLength +
  174.                              Srf1 -> VOrder) / 2];
  175.  
  176.     /* Subdivide along V. */
  177.     /* Subdivide along U. */
  178.     Srf1a = BspSrfSubdivAtParam(Srf1, SubdivVal, CAGD_CONST_V_DIR);
  179.     Srf1b = Srf1a -> Pnext;
  180.     Srf1a -> Pnext = NULL;
  181.  
  182.     Srf2a = BspSrfSubdivAtParam(Srf2, SubdivVal, CAGD_CONST_V_DIR);
  183.     Srf2b = Srf2a -> Pnext;
  184.     Srf2a -> Pnext = NULL;
  185.  
  186.     SrfA = BspSrfMultAux(Srf1a, Srf2a);
  187.     SrfB = BspSrfMultAux(Srf1b, Srf2b);
  188.     CagdSrfFree(Srf1a);
  189.     CagdSrfFree(Srf1b);
  190.     CagdSrfFree(Srf2a);
  191.     CagdSrfFree(Srf2b);
  192.  
  193.     ProdSrf = CagdMergeSrfSrf(SrfA, SrfB, CAGD_CONST_V_DIR, TRUE);
  194.     CagdSrfFree(SrfA);
  195.     CagdSrfFree(SrfB);
  196.     }
  197.     else {
  198.     int i;
  199.     CagdRType UMin, UMax, VMin, VMax;
  200.     CagdSrfStruct
  201.         *Srf1Bzr = CnvrtBspline2BezierSrf(Srf1),
  202.         *Srf2Bzr = CnvrtBspline2BezierSrf(Srf2),
  203.         *ProdSrfAux = BzrSrfMult(Srf1Bzr, Srf2Bzr);
  204.  
  205.     CagdSrfDomain(Srf1, &UMin, &UMax, &VMin, &VMax);
  206.     ProdSrf = CnvrtBezier2BsplineSrf(ProdSrfAux);
  207.     for (i = 0; i < ProdSrf -> UOrder; i++) {
  208.         ProdSrf -> UKnotVector[i] = UMin;
  209.         ProdSrf -> UKnotVector[i + ProdSrf -> UOrder] = UMax;
  210.     }
  211.     for (i = 0; i < ProdSrf -> VOrder; i++) {
  212.         ProdSrf -> VKnotVector[i] = VMin;
  213.         ProdSrf -> VKnotVector[i + ProdSrf -> VOrder] = VMax;
  214.     }
  215.  
  216.     CagdSrfFree(Srf1Bzr);
  217.     CagdSrfFree(Srf2Bzr);
  218.     CagdSrfFree(ProdSrfAux);
  219.     }
  220.  
  221.     return ProdSrf;
  222. }
  223.  
  224. /******************************************************************************
  225. * Given a rational bspline curve - computes its derivative curve using the    *
  226. * quotient rule for differentiation.                          *
  227. ******************************************************************************/
  228. CagdCrvStruct *BspCrvDeriveRational(CagdCrvStruct *Crv)
  229. {
  230.     CagdCrvStruct *CrvW, *CrvX, *CrvY, *CrvZ, *DCrvW, *DCrvX, *DCrvY, *DCrvZ,
  231.     *TCrv1, *TCrv2, *DeriveCrv;
  232.  
  233.     CagdCrvSplitScalar(Crv, &CrvW, &CrvX, &CrvY, &CrvZ);
  234.     if (CrvW)
  235.     DCrvW = BspCrvDerive(CrvW);
  236.     else
  237.     FATAL_ERROR(CAGD_ERR_RATIONAL_EXPECTED);
  238.  
  239.     if (CrvX) {
  240.     DCrvX = BspCrvDerive(CrvX);
  241.  
  242.     TCrv1 = BspCrvMult(DCrvX, CrvW);
  243.     TCrv2 = BspCrvMult(CrvX, DCrvW);
  244.  
  245.     CagdCrvFree(CrvX);
  246.     CrvX = CagdCrvSub(TCrv1, TCrv2);
  247.     CagdCrvFree(TCrv1);
  248.     CagdCrvFree(TCrv2);
  249.     }
  250.     if (CrvY) {
  251.     DCrvY = BspCrvDerive(CrvY);
  252.  
  253.     TCrv1 = BspCrvMult(DCrvY, CrvW);
  254.     TCrv2 = BspCrvMult(CrvY, DCrvW);
  255.  
  256.     CagdCrvFree(CrvY);
  257.     CrvY = CagdCrvSub(TCrv1, TCrv2);
  258.     CagdCrvFree(TCrv1);
  259.     CagdCrvFree(TCrv2);
  260.     }
  261.     if (CrvZ) {
  262.     DCrvZ = BspCrvDerive(CrvZ);
  263.  
  264.     TCrv1 = BspCrvMult(DCrvZ, CrvW);
  265.     TCrv2 = BspCrvMult(CrvZ, DCrvW);
  266.  
  267.     CagdCrvFree(CrvZ);
  268.     CrvZ = CagdCrvSub(TCrv1, TCrv2);
  269.     CagdCrvFree(TCrv1);
  270.     CagdCrvFree(TCrv2);
  271.     }
  272.     
  273.     TCrv1 = BspCrvMult(CrvW, CrvW);
  274.     CagdCrvFree(CrvW);
  275.     CrvW = TCrv1;
  276.  
  277.     if (!CagdMakeCrvsCompatible(&CrvW, &CrvX, TRUE, TRUE) ||
  278.     !CagdMakeCrvsCompatible(&CrvW, &CrvY, TRUE, TRUE) ||
  279.     !CagdMakeCrvsCompatible(&CrvW, &CrvZ, TRUE, TRUE))
  280.     FATAL_ERROR(CAGD_ERR_CRV_FAIL_CMPT);
  281.  
  282.     DeriveCrv = CagdCrvMergeScalar(CrvW, CrvX, CrvY, CrvZ);
  283.  
  284.     if (CrvX) {
  285.     CagdCrvFree(CrvX);
  286.     CagdCrvFree(DCrvX);
  287.     }
  288.     if (CrvY) {
  289.     CagdCrvFree(CrvY);
  290.     CagdCrvFree(DCrvY);
  291.     }
  292.     if (CrvZ) {
  293.     CagdCrvFree(CrvZ);
  294.     CagdCrvFree(DCrvZ);
  295.     }
  296.     if (CrvW) {
  297.     CagdCrvFree(CrvW);
  298.     CagdCrvFree(DCrvW);
  299.     }
  300.  
  301.     return DeriveCrv;
  302. }
  303.  
  304. /******************************************************************************
  305. * Given a rational bezier surface - computes its derivative curve using the   *
  306. * quotient rule for differentiation.                          *
  307. ******************************************************************************/
  308. CagdSrfStruct *BspSrfDeriveRational(CagdSrfStruct *Srf, CagdSrfDirType Dir)
  309. {
  310.     CagdSrfStruct *SrfW, *SrfX, *SrfY, *SrfZ, *DSrfW, *DSrfX, *DSrfY, *DSrfZ,
  311.     *TSrf1, *TSrf2, *DeriveSrf;
  312.  
  313.     CagdSrfSplitScalar(Srf, &SrfW, &SrfX, &SrfY, &SrfZ);
  314.     if (SrfW)
  315.     DSrfW = BspSrfDerive(SrfW, Dir);
  316.     else
  317.     FATAL_ERROR(CAGD_ERR_RATIONAL_EXPECTED);
  318.  
  319.     if (SrfX) {
  320.     DSrfX = BspSrfDerive(SrfX, Dir);
  321.  
  322.     TSrf1 = BspSrfMult(DSrfX, SrfW);
  323.     TSrf2 = BspSrfMult(SrfX, DSrfW);
  324.  
  325.     CagdSrfFree(SrfX);
  326.     SrfX = CagdSrfSub(TSrf1, TSrf2);
  327.     CagdSrfFree(TSrf1);
  328.     CagdSrfFree(TSrf2);
  329.     }
  330.     if (SrfY) {
  331.     DSrfY = BspSrfDerive(SrfY, Dir);
  332.  
  333.     TSrf1 = BspSrfMult(DSrfY, SrfW);
  334.     TSrf2 = BspSrfMult(SrfY, DSrfW);
  335.  
  336.     CagdSrfFree(SrfY);
  337.     SrfY = CagdSrfSub(TSrf1, TSrf2);
  338.     CagdSrfFree(TSrf1);
  339.     CagdSrfFree(TSrf2);
  340.     }
  341.     if (SrfZ) {
  342.     DSrfZ = BspSrfDerive(SrfZ, Dir);
  343.  
  344.     TSrf1 = BspSrfMult(DSrfZ, SrfW);
  345.     TSrf2 = BspSrfMult(SrfZ, DSrfW);
  346.  
  347.     CagdSrfFree(SrfZ);
  348.     SrfZ = CagdSrfSub(TSrf1, TSrf2);
  349.     CagdSrfFree(TSrf1);
  350.     CagdSrfFree(TSrf2);
  351.     }
  352.     
  353.     TSrf1 = BspSrfMult(SrfW, SrfW);
  354.     CagdSrfFree(SrfW);
  355.     SrfW = TSrf1;
  356.  
  357.     if (!CagdMakeSrfsCompatible(&SrfW, &SrfX, TRUE, TRUE, TRUE, TRUE) ||
  358.     !CagdMakeSrfsCompatible(&SrfW, &SrfY, TRUE, TRUE, TRUE, TRUE) ||
  359.     !CagdMakeSrfsCompatible(&SrfW, &SrfZ, TRUE, TRUE, TRUE, TRUE))
  360.     FATAL_ERROR(CAGD_ERR_SRF_FAIL_CMPT);
  361.  
  362.     DeriveSrf = CagdSrfMergeScalar(SrfW, SrfX, SrfY, SrfZ);
  363.  
  364.     if (SrfX) {
  365.     CagdSrfFree(SrfX);
  366.     CagdSrfFree(DSrfX);
  367.     }
  368.     if (SrfY) {
  369.     CagdSrfFree(SrfY);
  370.     CagdSrfFree(DSrfY);
  371.     }
  372.     if (SrfZ) {
  373.     CagdSrfFree(SrfZ);
  374.     CagdSrfFree(DSrfZ);
  375.     }
  376.     if (SrfW) {
  377.     CagdSrfFree(SrfW);
  378.     CagdSrfFree(DSrfW);
  379.     }
  380.  
  381.     return DeriveSrf;
  382. }
  383.